1   /*
2    * Copyright (C) 2008 The Guava Authors
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package com.google.common.collect.testing.testers;
18  
19  import static com.google.common.collect.testing.features.CollectionFeature.ALLOWS_NULL_QUERIES;
20  import static com.google.common.collect.testing.features.CollectionFeature.ALLOWS_NULL_VALUES;
21  import static com.google.common.collect.testing.features.CollectionFeature.FAILS_FAST_ON_CONCURRENT_MODIFICATION;
22  import static com.google.common.collect.testing.features.CollectionFeature.SUPPORTS_REMOVE;
23  import static com.google.common.collect.testing.features.CollectionSize.SEVERAL;
24  import static com.google.common.collect.testing.features.CollectionSize.ZERO;
25  
26  import com.google.common.annotations.GwtCompatible;
27  import com.google.common.collect.testing.AbstractCollectionTester;
28  import com.google.common.collect.testing.WrongType;
29  import com.google.common.collect.testing.features.CollectionFeature;
30  import com.google.common.collect.testing.features.CollectionSize;
31  
32  import java.util.ConcurrentModificationException;
33  import java.util.Iterator;
34  
35  /**
36   * A generic JUnit test which tests {@code remove} operations on a collection.
37   * Can't be invoked directly; please see
38   * {@link com.google.common.collect.testing.CollectionTestSuiteBuilder}.
39   *
40   * @author George van den Driessche
41   */
42  @SuppressWarnings("unchecked") // too many "unchecked generic array creations"
43  @GwtCompatible
44  public class CollectionRemoveTester<E> extends AbstractCollectionTester<E> {
45    @CollectionFeature.Require(SUPPORTS_REMOVE)
46    @CollectionSize.Require(absent = ZERO)
47    public void testRemove_present() {
48      int initialSize = collection.size();
49      assertTrue("remove(present) should return true",
50          collection.remove(samples.e0));
51      assertEquals("remove(present) should decrease a collection's size by one.",
52          initialSize - 1, collection.size());
53      expectMissing(samples.e0);
54    }
55  
56    @CollectionFeature.Require({SUPPORTS_REMOVE,
57        FAILS_FAST_ON_CONCURRENT_MODIFICATION})
58    @CollectionSize.Require(SEVERAL)
59    public void testRemovePresentConcurrentWithIteration() {
60      try {
61        Iterator<E> iterator = collection.iterator();
62        assertTrue(collection.remove(samples.e0));
63        iterator.next();
64        fail("Expected ConcurrentModificationException");
65      } catch (ConcurrentModificationException expected) {
66        // success
67      }
68    }
69  
70    @CollectionFeature.Require(SUPPORTS_REMOVE)
71    public void testRemove_notPresent() {
72      assertFalse("remove(notPresent) should return false",
73          collection.remove(samples.e3));
74      expectUnchanged();
75    }
76  
77    @CollectionFeature.Require({SUPPORTS_REMOVE, ALLOWS_NULL_VALUES})
78    @CollectionSize.Require(absent = ZERO)
79    public void testRemove_nullPresent() {
80      collection = getSubjectGenerator().create(createArrayWithNullElement());
81  
82      int initialSize = collection.size();
83      assertTrue("remove(null) should return true", collection.remove(null));
84      assertEquals("remove(present) should decrease a collection's size by one.",
85          initialSize - 1, collection.size());
86      expectMissing((E) null);
87    }
88  
89    @CollectionFeature.Require(absent = SUPPORTS_REMOVE)
90    @CollectionSize.Require(absent = ZERO)
91    public void testRemove_unsupported() {
92      try {
93        collection.remove(samples.e0);
94        fail("remove(present) should throw UnsupportedOperationException");
95      } catch (UnsupportedOperationException expected) {
96      }
97      expectUnchanged();
98      assertTrue("remove(present) should not remove the element",
99          collection.contains(samples.e0));
100   }
101 
102   @CollectionFeature.Require(absent = SUPPORTS_REMOVE)
103   public void testRemove_unsupportedNotPresent() {
104     try {
105       assertFalse("remove(notPresent) should return false or throw "
106           + "UnsupportedOperationException",
107           collection.remove(samples.e3));
108     } catch (UnsupportedOperationException tolerated) {
109     }
110     expectUnchanged();
111     expectMissing(samples.e3);
112   }
113 
114   @CollectionFeature.Require(
115       value = SUPPORTS_REMOVE,
116       absent = ALLOWS_NULL_QUERIES)
117   public void testRemove_nullNotSupported() {
118     try {
119       assertFalse("remove(null) should return false or throw "
120           + "NullPointerException",
121           collection.remove(null));
122     } catch (NullPointerException tolerated) {
123     }
124     expectUnchanged();
125   }
126 
127   @CollectionFeature.Require({SUPPORTS_REMOVE, ALLOWS_NULL_QUERIES})
128   public void testRemove_nullAllowed() {
129     assertFalse("remove(null) should return false", collection.remove(null));
130     expectUnchanged();
131   }
132 
133   @CollectionFeature.Require(absent = SUPPORTS_REMOVE)
134   @CollectionSize.Require(absent = ZERO)
135   public void testIteratorRemove_unsupported() {
136     Iterator<E> iterator = collection.iterator();
137     iterator.next();
138     try {
139       iterator.remove();
140       fail("iterator.remove() should throw UnsupportedOperationException");
141     } catch (UnsupportedOperationException expected) {
142     }
143     expectUnchanged();
144     assertTrue(collection.contains(samples.e0));
145   }
146 
147   @CollectionFeature.Require(SUPPORTS_REMOVE)
148   public void testRemove_wrongType() {
149     try {
150       assertFalse(collection.remove(WrongType.VALUE));
151     } catch (ClassCastException tolerated) {
152     }
153     expectUnchanged();
154   }
155 }